#pragma once

#include "Core/Point2.h"
#include "View/Camera.h"
struct _GLMmodel;
#include <map>
#include <memory>

class Application {
public: // Constructors
	Application();
	~Application();

public: // Members
	void run();
	
public: // glutCallbacks
	void onRender();
	void onSpecialKey( int key, int x, int y );
	void onKeyDown( unsigned char ch, int x, int y );
	void onKeyUp( unsigned char ch, int x, int y );
	void onMotion( int x, int y );
	void onMouse( int button, int state, int x, int y );
	void onReshape( int w, int h );
	void onMenu( int idx );
	void onIdle();

public: // glut interface
	static void render();
	static void keydown( unsigned char, int, int );
	static void keyup( unsigned char, int, int );
	static void motion( int, int );
	static void mouse( int, int, int, int );
	static void reshape( int, int );
	static void menu( int );
	static void idle();
	static void specialkey( int, int, int );

private: // Non-copyable
	Application( const Application& );
	Application& operator = ( const Application& );
	
private: // Typedefs
	typedef Core::Point2i Point2i;
	typedef View::Camera Camera;

private: // Members
	bool keys[256];			// Keyboard state
	int previousTicks;		// Timing control
	int currentTicks;		
	bool mouseLook;			// Mouse control
	float pitching;			
	float yawing;			 
	float rolling;			// Camera control (FPS-style)
	float pitch;
	float yaw;
	float roll;
	bool mouseMoved;
	Camera cam;
	Point2i mouseAnchor;
	Point2i screenSize;		// Screen state
	std::shared_ptr<_GLMmodel> pmodel1;
	unsigned cityScene;
	unsigned spaceScene;
	int currentScene;
	float aspectMod;		// Perspective state
	float viewMod;

public: // Helper members
	// "User data" for glut windows
	static std::map<int, Application* const> instanceMap;
};